package com.util.concurrent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 *  * 详细讲解  https://juejin.im/entry/58fada5d570c350058d3aaad
 *
 *  五种状态
 *      RUNNING ：能接受新提交的任务，并且也能处理阻塞队列中的任务；
 *      SHUTDOWN：关闭状态，不再接受新提交的任务，但却可以继续处理阻塞队列中已保存的任务。在线程池处于 RUNNING 状态时，调用 shutdown()方法会使线程池进入到该状态。（finalize() 方法在执行过程中也会调用shutdown()方法进入该状态）；
 *      STOP：不能接受新任务，也不处理队列中的任务，会中断正在处理任务的线程。在线程池处于 RUNNING 或 SHUTDOWN 状态时，调用 shutdownNow() 方法会使线程池进入到该状态；
 *      TIDYING：如果所有的任务都已终止了，workerCount (有效线程数) 为0，线程池进入该状态后会调用 terminated() 方法进入TERMINATED 状态。
 *      TERMINATED：在terminated() 方法执行完后进入该状态，默认terminated()方法中什么也没有做。
 *      进入TERMINATED的条件如下：
 *          线程池不是RUNNING状态；
 *          线程池状态不是TIDYING状态或TERMINATED状态；
 *          如果线程池状态是SHUTDOWN并且workerQueue为空；
 *          workerCount为0；
 *          设置TIDYING状态成功。
 *
 *     当有新任务在execute()方法提交时，会执行以下判断：
 *          如果运行的线程少于 corePoolSize，则创建新线程来处理任务，即使线程池中的其他线程是空闲的；
 *          如果线程池中的线程数量大于等于 corePoolSize 且小于 maximumPoolSize，则只有当workQueue满时才创建新的线程去处理任务；
 *          如果设置的corePoolSize 和 maximumPoolSize相同，则创建的线程池的大小是固定的，这时如果有新任务提交，若workQueue未满，则将请求放入workQueue中，等待有空闲的线程去从workQueue中取任务并处理；
 *          如果运行的线程数量大于等于maximumPoolSize，这时如果workQueue已经满了，则通过handler所指定的策略来处理任务；
 *
 *
 * 运行完看结果大吃一惊，results是变运行变输出的，贼几把屌
 *
 *
 *  它们通常可以在执行大量异步任务时提供增强的性能，并且还可以提供绑定和管理资源（包括执行任务集时使用的线程）的方法。
 *  https://www.cnblogs.com/trust-freedom/p/6594270.html
 *  https://zhuanlan.zhihu.com/p/32867181
 * Created by yangliwei on 2018/4/13.
 */
public class ThreadPoolExecutorDemo {

    public ThreadPoolExecutorDemo() {
    }

    //仿造tomcat ContainerBase里面的startInternal方法
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ThreadPoolExecutor pool = (ThreadPoolExecutor) Executors.newCachedThreadPool();
//        new StartChild(); 可以直接new一个内部类对象；
        List<Future<String>> results = new ArrayList<>();
        for(int i =0;i<100;i++){
            results.add(pool.submit(new StartChild("thread:"+i+" ")));
        }
        for(int i=0;i<results.size();i++){
            System.out.println("results is : "+results.get(i).get());
        }

    }

    //只有静态内部类，静态外部类编译过不去
    private static class StartChild implements Callable<String>{

        private String name;
        public StartChild(String name) {
            this.name = name;
        }

        @Override
        public String call() throws Exception {
            for(int i = 0;i<100;i++){
                System.out.println(this.name+"   "+i);
            }
            System.out.println(name +" is finished");
            return this.name +" is success";
        }

    }

}
